package com.mmaingenieria.MMAGestor.MySQL;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

import org.apache.log4j.Logger;

import com.mmaingenieria.MMAGestor.beans.Usuario;
import com.mmaingenieria.MMAGestor.controller.usuarios.FiltroUsuarios;
import com.mmaingenieria.MMAGestor.database.MySQLDAOFactory;
import com.mmaingenieria.MMAGestor.interfaces.InterfaceUsuarioDAO;

public class MySQLUsuarioDAO implements InterfaceUsuarioDAO{
	//Construtor
    //*************************************************************************
    public MySQLUsuarioDAO() {
       
    }
    
    
    //Metodos que hay que implementar por extender de InterfaceUsuario
    //*************************************************************************
        
    //coger un usuario por nombre y pass (para verificar Login)
	public Usuario getUsuarioByUserAndPass(String _usuario, String _password) throws Exception{
		Connection conexion = null;
		try {
			Usuario usuario = null;
	        String sql = "SELECT usuario_id, usuario, nombre, rol, estado FROM mmagestor.usuario WHERE usuario COLLATE utf8_bin = ? and password COLLATE utf8_bin = ?";              
            conexion = MySQLDAOFactory.conectar();         
            PreparedStatement stmt = conexion.prepareStatement(sql);//preparas la query
            stmt.setString(1,_usuario); //le pasamos el primer parametro
            stmt.setString(2, _password);//le pasamos el segundo parametro
            ResultSet resultadoQuery = stmt.executeQuery();//realizas la query                   
            while (resultadoQuery.next()) {//recorres el resultado
            	usuario =instanciarUsuarioSesion(resultadoQuery);//
            }
            return usuario;
        } catch (Exception e) {
        	Logger.getLogger(this.getClass()).error("Excepcion generada en getUsuarioByUserAndPass");
        	throw e;        		
        } finally {
            MySQLDAOFactory.desconectar(conexion);
        }		
	}
	
	//Coger toda la lista de usuarios (para mostrar listas)
    public ArrayList<Usuario> getUsuarios() throws Exception{
    	Connection conexion = null;
    	try{
    		ArrayList<Usuario> listaUsuarios = null;//creo un arraylist de tipo usuarios
    		String sql =  "SELECT usuario_id, usuario, nombre, apellido1, apellido2, nif, email, rol, estado, cliente_id, observaciones, created_by, date_created, modified_by, last_update FROM mmagestor.usuario";                
            conexion = MySQLDAOFactory.conectar();
            PreparedStatement stmt = conexion.prepareStatement(sql);//preparas la query
            ResultSet resultadoQuery = stmt.executeQuery();//realizas la query
            listaUsuarios = new ArrayList<Usuario>();
            while (resultadoQuery.next()) {//recorres el resultado
                listaUsuarios.add(instanciarUsuario(resultadoQuery));//por cada recordset lo pasa a usuario y lo añades a la lista
            }
            return listaUsuarios;
        } catch (Exception e) {
        	Logger.getLogger(this.getClass()).error("Excepcion generada en getUsuarios");
        	throw e;
        } finally {
            MySQLDAOFactory.desconectar(conexion);
        }
    }
    
  //Coger lista de usuarios filtrada (para mostrar listas filtradas)
    public ArrayList<Usuario> getUsuariosByFilter(FiltroUsuarios filtro) throws Exception{
    	Connection conexion = null;
    	try{
    		ArrayList<Usuario> listaUsuarios = null;//creo un arraylist de tipo usuarios
    		String sql =  "SELECT usuario_id, usuario, nombre, apellido1, apellido2, nif, email, rol, estado, cliente_id, observaciones, created_by, date_created, modified_by, last_update FROM mmagestor.usuario " + filtro.getFiltroSql();                
    		conexion = MySQLDAOFactory.conectar();
            PreparedStatement stmt = conexion.prepareStatement(sql);//preparas la query
            ResultSet resultadoQuery = stmt.executeQuery();//realizas la query
            listaUsuarios = new ArrayList<Usuario>();
            while (resultadoQuery.next()) {//recorres el resultado
                listaUsuarios.add(instanciarUsuario(resultadoQuery));//por cada recordset lo pasa a usuario y lo añades a la lista
            }
            return listaUsuarios;
        } catch (Exception e) {
        	Logger.getLogger(this.getClass()).error("Excepcion generada en getUsuariosByFilter");
        	throw e;
        } finally {
            MySQLDAOFactory.desconectar(conexion);
        }
    }
    
    //coger usuario por id (para buscar un usuario)
  	public ArrayList<Usuario> getUsuarioById(int _id) throws Exception{
  		Connection conexion = null;
  		try {
	  		ArrayList<Usuario> listaUsuarios = null;//creo un arraylist de tipo usuarios 
	  		String sql = "SELECT usuario_id, usuario, nombre, apellido1, apellido2, nif, email, rol, estado, cliente_id, observaciones, created_by, date_created, modified_by, last_update FROM mmagestor.usuario WHERE usuario_id=?"; 
	  		conexion = MySQLDAOFactory.conectar();
	  		PreparedStatement stmt = conexion.prepareStatement(sql);//preparas la query
			stmt.setInt(1,_id); //le pasamos el primer parametro
			ResultSet resultadoquery = stmt.executeQuery();//realizas la query        
			listaUsuarios = new ArrayList<Usuario>();
			while (resultadoquery.next()) {//recorres el resultado
				listaUsuarios.add(instanciarUsuario(resultadoquery));//por cada recordset lo pasa a usuario y lo añades a la lista
			}
			return listaUsuarios;
		} catch (Exception e) {
			Logger.getLogger(this.getClass()).error("Excepcion generada en getUsuariosById");
			throw e;
		} finally {
			MySQLDAOFactory.desconectar(conexion);
		}  		
  	}
  	
  	//Añadir un Usuario (para crear usuarios)
  	public boolean addUsuario(Usuario usuarioNuevo) throws Exception{
  		Connection conexion = null;
  		boolean resultado = false;
  		try { 			
  			//con clave encripatda
  			//sql = "INSERT INTO mmagestor.usuario (usuario, password, nombre, apellido1, apellido2, nif, email, rol, estado, cliente_id, observaciones, created_by, date_created, modified_by) VALUES (?,MD5(?),?,?,?,?,?,?,?,?,?,?,?,?)";
  			//Sin clave encriptada
  			String sql = "INSERT INTO mmagestor.usuario (usuario, password, nombre, apellido1, apellido2, nif, email, rol, estado, cliente_id, observaciones, created_by, date_created, modified_by) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
  			conexion = MySQLDAOFactory.conectar();
          	PreparedStatement stmt = conexion.prepareStatement(sql);//preparas la query
          	stmt.setString(1,usuarioNuevo.getUsuario());
          	stmt.setString(2,usuarioNuevo.getPassword());
          	stmt.setString(3,usuarioNuevo.getNombre());
          	stmt.setString(4,usuarioNuevo.getApellido1());
          	stmt.setString(5,usuarioNuevo.getApellido2());
          	stmt.setString(6,usuarioNuevo.getNif());
          	stmt.setString(7,usuarioNuevo.getEmail());
          	stmt.setInt(8,usuarioNuevo.getNumeroRol());
          	stmt.setInt(9,usuarioNuevo.getNumeroEstado());       	
          	if (usuarioNuevo.getClienteId() == 0){ //si el int es cero (un int no puede ser null) le paso null.
          		stmt.setString(10, null);
          	}
          	else{// sino le paso el entero correspondiente
          		stmt.setInt(10,usuarioNuevo.getClienteId());
          	}
          	stmt.setString(11,usuarioNuevo.getObservaciones());
          	stmt.setInt(12,usuarioNuevo.getCreatedBy());
          	stmt.setTimestamp(13,usuarioNuevo.getDateCreated());
          	stmt.setInt(14,usuarioNuevo.getModifiedBy());        	
          	stmt.executeUpdate();//ejecutas la query         	
          	resultado= true;          	
  		}catch (Exception e) {
  			resultado = false;
  			Logger.getLogger(this.getClass()).error("Excepcion generada en addUsuario");
  			throw e;
  		}finally {
  			MySQLDAOFactory.desconectar(conexion);
  		}
  		return resultado;
	}
  	
  	//metodo que obtiene el Id por Nif
	public int getIdByNif(String _nif) throws Exception {
		Connection conexion = null;
		try {
			int id=-1;
			Usuario usuario = null;
	        String sql = "SELECT usuario_id FROM mmagestor.usuario WHERE nif = ?";              
            conexion = MySQLDAOFactory.conectar();         
            PreparedStatement stmt = conexion.prepareStatement(sql);//preparas la query
            stmt.setString(1,_nif); //le pasamos el primer parametro
            ResultSet resultadoQuery = stmt.executeQuery();//realizas la query                   
            while (resultadoQuery.next()) {//recorres el resultado
            	usuario =instanciarUsuarioId(resultadoQuery);//
            	id= usuario.getId();
            }           
            return id;
        } catch (Exception e) {
        	Logger.getLogger(this.getClass()).error("Excepcion generada en getIdByNif");
        	throw e;        		
        } finally {
            MySQLDAOFactory.desconectar(conexion);
        }		
	}
	//metodo que actualiza un usuario
	public boolean updateUsuario(Usuario usuarioModificado) throws Exception {	
		Connection conexion = null;
		boolean resultado=false;
		try{			
			String sql ="UPDATE mmagestor.usuario SET usuario =?, nombre=?, apellido1 =?, apellido2 =?, nif =?, email =?, rol =?, estado =?, cliente_id=?, observaciones=?, modified_by=? WHERE usuario_id = ?";
			conexion = MySQLDAOFactory.conectar();
			PreparedStatement stmt = conexion.prepareStatement(sql);//preparas la query
        	stmt.setString(1,usuarioModificado.getUsuario());
        	stmt.setString(2,usuarioModificado.getNombre());
        	stmt.setString(3,usuarioModificado.getApellido1());
        	stmt.setString(4,usuarioModificado.getApellido2());
        	stmt.setString(5,usuarioModificado.getNif());
        	stmt.setString(6,usuarioModificado.getEmail());
        	stmt.setInt(7,usuarioModificado.getNumeroRol());
        	stmt.setInt(8,usuarioModificado.getNumeroEstado());       	
        	if (usuarioModificado.getClienteId() == 0){ //si el int es cero (un int no puede ser null) le paso null.
        		stmt.setString(9, null);
        	}
        	else{// sino le paso el entero correspondiente
        		stmt.setInt(9,usuarioModificado.getClienteId());
        	}
        	stmt.setString(10, usuarioModificado.getObservaciones());
        	stmt.setInt(11, usuarioModificado.getModifiedBy());
        	stmt.setInt(12,usuarioModificado.getId());        	
        	stmt.executeUpdate();//ejecutas la query			
			resultado = true;			
		}catch (Exception e){			
			resultado=false;
			Logger.getLogger(this.getClass()).error("Excepcion generada en updateUsuario");
        	throw e;
		}
		finally {
            MySQLDAOFactory.desconectar(conexion);
        }
		return 	resultado;
	}
	
	//metodo que borra un usuario
	public boolean deleteUsuario(int usuario_id) throws Exception {		
		Connection conexion = null;
		boolean resultado = false;
		try{			
			String sql = "DELETE FROM mmagestor.usuario WHERE usuario_id =?";
			conexion = MySQLDAOFactory.conectar();
			PreparedStatement stmt = conexion.prepareStatement(sql);//preparas la query
        	stmt.setInt(1,usuario_id);
        	stmt.executeUpdate();//ejecutas la query
			resultado = true;						
		}catch (Exception e){
			resultado = false;
			Logger.getLogger(this.getClass()).error("Excepcion generada en updateUsuario");
        	throw e;
		}
		finally {
            MySQLDAOFactory.desconectar(conexion);
        }
		return resultado;
	}
	
	//metodo que devuekve true si un usuario se puede borrar porque no ha creado ni modificado a otro usuario
	public boolean actionUsuario(int usuario_id) throws Exception {
		Connection conexion = null;
		boolean resultado = false;
		try{			
			Usuario usuario= null;
			String sql = "SELECT usuario_id FROM mmagestor.usuario WHERE created_by =? OR modified_by=?";
			conexion = MySQLDAOFactory.conectar();
			PreparedStatement stmt = conexion.prepareStatement(sql);//preparas la query
        	stmt.setInt(1,usuario_id);
        	stmt.setInt(2,usuario_id);
        	ResultSet resultadoQuery = stmt.executeQuery();//realizas la query                   
        	while (resultadoQuery.next()) {//recorres el resultado
            	usuario =instanciarUsuarioId(resultadoQuery);//
            }
            if (usuario == null){//si el usuario es null es que no ha modificado ni creado ninguno y se puede borrar
            	resultado=true;
            }						
		}catch (Exception e){
			resultado = false;
			Logger.getLogger(this.getClass()).error("Excepcion generada en accionUsuario");
        	throw e;
		}
		finally {
            MySQLDAOFactory.desconectar(conexion);
        }
		return resultado;
	} 
    
	//metodo que actualiza un pass de un usuario
	public boolean updatePassById(int _usuario_id, String nuevaPass) throws Exception {	
		Connection conexion = null;
		boolean resultado=false;
		try{
			String sql ="UPDATE mmagestor.usuario SET password = MD5(?) WHERE usuario_id = ?";
			conexion = MySQLDAOFactory.conectar();
			PreparedStatement stmt = conexion.prepareStatement(sql);//preparas la query
        	stmt.setString(1,nuevaPass);
        	stmt.setInt(2,_usuario_id);      	
        	stmt.executeUpdate();//ejecutas la query			
			resultado = true;			
		}catch (Exception e){			
			resultado = false;
			Logger.getLogger(this.getClass()).error("Excepcion generada en updateUsuario");
        	throw e;
		}
		finally {
            MySQLDAOFactory.desconectar(conexion);
        }
		return 	resultado;
	}
	
	//metodo que recoje la pass de un usuario
	public String getPassById(int _usuario_id) throws Exception {	
		Connection conexion = null;
		String pass = null;
		try{
			String sql ="SELECT password FROM mmagestor.usuario WHERE usuario_id = ?";
			conexion = MySQLDAOFactory.conectar();
			PreparedStatement stmt = conexion.prepareStatement(sql);//preparas la query
        	stmt.setInt(1,_usuario_id);      	
        	ResultSet resultadoQuery = stmt.executeQuery();//ejecutas la query
        	while (resultadoQuery.next()) {//recorres el resultado
            	pass =instanciarPass(resultadoQuery);//
        	}			
		}catch (Exception e){			
			pass = null;
			Logger.getLogger(this.getClass()).error("Excepcion generada en getPassById");
        	throw e;
		}
		finally {
            MySQLDAOFactory.desconectar(conexion);
        }
		return pass;
	}

    
    
    //Metodos Varios
    //*************************************************************************
    
	//metodo para pasar del recordset a tipo usuario con solo el Id.
    private Usuario instanciarUsuarioId (ResultSet rs){
    	Usuario u = new Usuario();
        try { 
            u.setId(rs.getInt("usuario_id"));
            return u;
        }catch (Exception ex) {
        	Logger.getLogger(this.getClass()).error("Excepcion generada en instanciando UsuarioId");
        	return null;
        }
    }
    //metodo para pasar del recordset a tipo String de password
    private String instanciarPass (ResultSet rs){
    	try{
    		String pass = rs.getString("password");
    		return pass;
    	}catch (Exception ex) {
        	Logger.getLogger(this.getClass()).error("Excepcion generada en instanciando Passsword");
        	return null;
        }
    }
    //metodo para pasar del recordset a tipo usuario Sesion, no le hace falta más datos.
    private Usuario instanciarUsuarioSesion (ResultSet rs){
     	Usuario u = new Usuario();
        try { 
        	//u.setId(rs.getInt("usuario_id"));
        	u= instanciarUsuarioId (rs);
            u.setUsuario(rs.getString("usuario"));
            u.setNombre(rs.getString("nombre"));
            u.setRol(rs.getInt("rol"));
            u.setEstado(rs.getInt("estado"));
            return u;
        }catch (Exception ex) {
        	Logger.getLogger(this.getClass()).error("Excepcion generada en instanciando UsuarioSesion");
        	return null;
        }          	
    }
        
	//metodo para pasar del recordset a tipo usuario
    private Usuario instanciarUsuario (ResultSet rs) {
    	Usuario u = new Usuario();
    	try {
            u = instanciarUsuarioSesion(rs);
            u.setApellido1(rs.getString("apellido1"));
            u.setApellido2(rs.getString("apellido2"));
            u.setNif(rs.getString("nif"));
            u.setEmail(rs.getString("email"));
            u.setClienteId(rs.getInt("cliente_id"));
            u.setObservaciones(rs.getString("observaciones"));
            u.setCreatedBy(rs.getInt("created_by"));
            u.setDateCreated(rs.getTimestamp("date_created"));
            u.setModifiedBy(rs.getInt("modified_by"));
            u.setLastUpdate(rs.getTimestamp("last_update"));
            return u;
        }catch (SQLException ex) {
        	Logger.getLogger(this.getClass()).error("Excepcion generada en instanciando Usuario");
        	return null;
        }       
    }
    
    

}
